package com.erpanderp.wam.ac.view.travel;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.SwingWorker;

import org.primefaces.context.RequestContext;

import com.erpanderp.wam.ac.model.entity.travel.Logistics;
import com.erpanderp.wam.ac.model.entity.travel.TravelLogistics;
import com.erpanderp.wam.ac.model.entity.travel.TravelRequest;
import com.erpanderp.wam.ac.model.service.travel.LogisticsDAO;
import com.erpanderp.wam.ac.model.service.travel.TravelLogisticsDAO;
import com.erpanderp.wam.ac.model.service.travel.TravelRequestDAO;
import com.erpanderp.wam.adm.model.entity.Module;
import com.erpanderp.wam.adm.model.service.ModuleDAO;
import com.erpanderp.wam.adm.view.UserMenuBean;
import com.erpanderp.wam.usm.model.entity.user.Employee;
import com.erpanderp.wam.usm.model.entity.user.WAMUser;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.EmailUtil;
import com.erpanderp.wam.util.ValidationUtil;
import com.erpanderp.wam.util.WAMHostManager;

@ManagedBean
@ViewScoped
public class TravelRequestsBean {

	HttpSession session = (HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(true);
	private WAMUser wamUser = (WAMUser) session.getAttribute(CommonLookup.SESSION_ATTRIBUTE_WAMUSER);
	HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
	ServletContext context = (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();

	private TimeZone timeZone = TimeZone.getDefault();
	private List<TravelRequest> myTravelRequests = new ArrayList<TravelRequest>();
	private List<TravelRequest> travelRequests = new ArrayList<TravelRequest>();
	private TravelRequest travelRequest = new TravelRequest();

	private Map<String, String> travelModesMap = CommonLookup.getTravelModesMap();
	private Map<String, String> natureOfWorksMap = CommonLookup.getNatureOfWorksMap();
	private Map<String, String> reimbursedByMap = CommonLookup.getReimbursedByMap();
	private List<TravelLogistics> travelLogistics = new ArrayList<TravelLogistics>();
	
	TravelRequestDAO travelRequestDAO = new TravelRequestDAO();
	TravelLogisticsDAO travelLogisticsDAO = new TravelLogisticsDAO();
	
	boolean FORM_VALID;
	EmailUtil emailUtil;
	String EMAIL_MESSAGE;
	
	public TravelRequestsBean() {
		if (wamUser != null) {
			
			if (request.getParameter("redirectfrom") != null && request.getParameter("redirectfrom").equals(CommonLookup.PAGE_DASHBOARD)) {
				
			}
			
			
			travelRequests = travelRequestDAO.getTravelRequestsByApproverId(wamUser.getEmployee().getEmployeeId(), null);
			myTravelRequests = travelRequestDAO.getTravelRequests(wamUser.getEmployee().getEmployeeId());
		}
	}

	public void viewOrEditTravelRequest(){
		System.out.println(travelRequest.getTravelRequestCode());	
		travelLogistics.clear();
		travelLogistics.addAll(travelRequest.getTravelLogistics());
	}
	
	public void dialogClose(ActionEvent e){
		//Replacing the arraylist content with original record from database...
		
		RequestContext.getCurrentInstance().execute("dialog.hide()");		
	}
	
	public void rejectTravelRequest(ActionEvent e){
		if(validateComment()){
			travelRequest.setDateModified(new Date());
			travelRequest.setModifiedBy(travelRequest.getApprover().getFirstName());
			travelRequest.setTravelStatus(CommonLookup.TRAVEL_REQUEST_STATUS_REJECTED);
			if(travelRequestDAO.updateTravelRequest(travelRequest) != null){
				FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_INFO, "Travel request is rejected.", ""));
				RequestContext.getCurrentInstance().execute("dialog.hide();");
				System.out.println(sendMessage());
			}else{
				FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Failed", ""));
				RequestContext.getCurrentInstance().execute("dialog.hide();");
			}	
		}
		
	}
	
	public void approveTravelRequest(ActionEvent e){
		if(validateComment()){
			travelRequest.setDateModified(new Date());
			travelRequest.setModifiedBy(travelRequest.getApprover().getFirstName());
			travelRequest.setTravelStatus(CommonLookup.TRAVEL_REQUEST_STATUS_APPROVED);
			if(travelRequestDAO.updateTravelRequest(travelRequest) != null){
				FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_INFO, "Travel request is approved.", ""));
				RequestContext.getCurrentInstance().execute("dialog.hide();");
				System.out.println(sendMessage());
			}else{
				FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Failed", ""));
				RequestContext.getCurrentInstance().execute("dialog.hide();");
			}	
		}
		
	}
	
	public String sendMessage(){
		Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
		
		emailUtil = new EmailUtil();
		if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {
			String[] to = { travelRequest.getEmployee().getFirstName() };
			emailUtil.setRecieverAddresses(to);
		} else {
			String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
			System.out.println(to);
			emailUtil.setRecieverAddresses(to);
		}
		
		String messageString = "Dear " + travelRequest.getEmployee().getFirstName() + " " + travelRequest.getEmployee().getLastName() + "<br />";
		SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
		if(travelRequest.getTravelStatus().equals(CommonLookup.TRAVEL_REQUEST_STATUS_APPROVED)){
			messageString += "<p>Your Travel Request " + travelRequest.getTravelRequestCode() + " is approved from " + format.format(travelRequest.getPeriodFrom()) + " to " + format.format(travelRequest.getPeriodTo()) + ".</p>"; 
		}else{
			messageString += "<p>Your Travel Request " + travelRequest.getTravelRequestCode() + " is rejected.</p>";
		}
						
		System.out.println(travelRequest.getApprovalComments());
		messageString += "<span style='font-weight: bold;'>Approval Comment: </span>" + travelRequest.getApprovalComments() +						
								"<br /><br />"+								
								"Thanks & Regards, <br />"+CommonLookup.WAM_DEVTEAM_SIGNATURE;;
		
		emailUtil = new EmailUtil();
		emailUtil.setMessage(messageString);
		emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");
		emailUtil.setSubject("WAM - Travel Request (" + travelRequest.getTravelRequestCode() + ")");

		SwingWorker worker = new SwingWorker<String, Object>() {
			@Override
			protected String doInBackground() throws Exception {
				EMAIL_MESSAGE = emailUtil.processAndSendEmail();
				return null;
			}

			@Override
			protected void done() {
					System.out.println("DONE " + EMAIL_MESSAGE);		
			}
		};
		worker.execute();
		System.out.println( "BEFORE RETURNING: " + EMAIL_MESSAGE);
		return EMAIL_MESSAGE;
	}
	
	public void updateTravelRequest(ActionEvent e){
		validate();
		if(FORM_VALID){
			System.out.println("FORM VALID...");
			if(FORM_VALID){
				System.out.println("Updating TravelRequest...");
				travelRequest.setDateModified(new Date());
				travelRequest.setModifiedBy(wamUser.getEmployee().getFirstName());
				travelRequest.setTravelStatus(CommonLookup.TRAVEL_REQUEST_STATUS_INPROCESS);
				if(travelRequestDAO.updateTravelRequest(travelRequest) != null){
					RequestContext.getCurrentInstance().addPartialUpdateTarget("travelRequestsForm");
					RequestContext.getCurrentInstance().execute("dialog.hide();");
					FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_INFO, "Travel Request updated.", ""));
				}else{
					FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Failed to update Travel Request", ""));
					RequestContext.getCurrentInstance().execute("dialog.show();");
				}
				
			}else{
				RequestContext.getCurrentInstance().execute("dialog.show();");			
			}
		}
		
	}
	
	public void validate(){
		FORM_VALID = true;		
		
		if(ValidationUtil.isEmpty(travelRequest.getEmergencyContact(), "Emergency Contact", "emergencyContact", FacesContext.getCurrentInstance()) != null){
			FORM_VALID = false;
		}
		if(ValidationUtil.isEmpty(travelRequest.getPeriodFrom() == null ? null : travelRequest.getPeriodFrom().toString(), "Travel Period From", "travelPeriodFrom", FacesContext.getCurrentInstance()) != null)
			FORM_VALID = false;
		
		if(ValidationUtil.isEmpty(travelRequest.getPeriodTo() == null ? null : travelRequest.getPeriodTo().toString(), "Travel Period To", "travelPeriodTo", FacesContext.getCurrentInstance()) != null)
			FORM_VALID = false;
				
		if(travelRequest.getTravelType().equals(CommonLookup.TRAVEL_DOMESTIC_VALUE)){
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_DO(), "Source City (Domestic)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_DO(), "Source Country (Domestic)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_DO(), "Destination City (Domestic)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_DO(), "Destination Country (Domestic)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
		}
		
		if(travelRequest.getTravelType().equals(CommonLookup.TRAVEL_OVERSEAS_VALUE)){
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_OS(), "Source City (Overseas)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_OS(), "Source Country (Overseas)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_OS(), "Destination City (Overseas)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_OS(), "Destination Country (Overseas)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
		}
		
		if(travelRequest.getTravelType().equals(CommonLookup.TRAVEL_BOTH_VALUE)){
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_DO(), "Source City (Domestic)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_DO(), "Source Country (Domestic)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_DO(), "Destination City (Domestic)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_DO(), "Destination Country (Domestic)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_OS(), "Source City (Overseas)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_OS(), "Source Country (Overseas)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_OS(), "Destination City (Overseas)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_OS(), "Destination Country (Overseas)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
		}	
		
		if(ValidationUtil.isEmpty(travelRequest.getClient(), "Client", "client", FacesContext.getCurrentInstance()) != null)
			FORM_VALID = false;
				
		if(ValidationUtil.isEmpty(travelRequest.getClientLocation(), "Client Location", "clientLocation", FacesContext.getCurrentInstance()) != null)
			FORM_VALID = false;
		
		System.out.println("FORM VALIDITY: " + FORM_VALID);
	}
	
	public void onCloseDialog(AjaxBehaviorEvent e){
		if(travelRequest.getEmployee().getEmployeeId().equals(wamUser.getEmployee().getEmployeeId())){
			System.out.println(myTravelRequests.indexOf(travelRequest));
			myTravelRequests.set(myTravelRequests.indexOf(travelRequest), travelRequestDAO.getTravelRequestById(travelRequest.getTravelRequestId()));	
		}else{
			System.out.println(travelRequests.indexOf(travelRequest));
			travelRequests.set(travelRequests.indexOf(travelRequest), travelRequestDAO.getTravelRequestById(travelRequest.getTravelRequestId()));
		}
		RequestContext.getCurrentInstance().addPartialUpdateTarget("travelRequestsForm");
	}
	
	
	
	
	private boolean validateComment(){
		if(ValidationUtil.isEmpty(travelRequest.getApprovalComments(), "Comments ", "", FacesContext.getCurrentInstance()) != null){
			return false;
		}else{
			return true;
		}
	}
	public List<TravelRequest> getTravelRequests() {
		return travelRequests;
	}

	public void setTravelRequests(List<TravelRequest> travelRequests) {
		this.travelRequests = travelRequests;
	}

	public TravelRequest getTravelRequest() {
		return travelRequest;
	}

	public void setTravelRequest(TravelRequest travelRequest) {
		this.travelRequest = travelRequest;
	}

	public Map<String, String> getTravelModesMap() {
		return travelModesMap;
	}

	public void setTravelModesMap(Map<String, String> travelModesMap) {
		this.travelModesMap = travelModesMap;
	}

	public Map<String, String> getNatureOfWorksMap() {
		return natureOfWorksMap;
	}

	public void setNatureOfWorksMap(Map<String, String> natureOfWorksMap) {
		this.natureOfWorksMap = natureOfWorksMap;
	}

	public Map<String, String> getReimbursedByMap() {
		return reimbursedByMap;
	}

	public void setReimbursedByMap(Map<String, String> reimbursedByMap) {
		this.reimbursedByMap = reimbursedByMap;
	}

	public List<TravelLogistics> getTravelLogistics() {
		return travelLogistics;
	}

	public void setTravelLogistics(List<TravelLogistics> travelLogistics) {
		this.travelLogistics = travelLogistics;
	}

	public WAMUser getWamUser() {
		return wamUser;
	}

	public void setWamUser(WAMUser wamUser) {
		this.wamUser = wamUser;
	}

	public List<TravelRequest> getMyTravelRequests() {
		return myTravelRequests;
	}

	public void setMyTravelRequests(List<TravelRequest> myTravelRequests) {
		this.myTravelRequests = myTravelRequests;
	}

	public TimeZone getTimeZone() {
		return timeZone;
	}

	public void setTimeZone(TimeZone timeZone) {
		this.timeZone = timeZone;
	}

}
